package vitaliy.bondar.diamondcave;

import java.io.IOException;

import org.andengine.audio.sound.Sound;
import org.andengine.audio.sound.SoundFactory;
import org.andengine.engine.Engine;
import org.andengine.engine.camera.BoundCamera;
import org.andengine.opengl.font.Font;
import org.andengine.opengl.font.FontFactory;
import org.andengine.opengl.texture.ITexture;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.atlas.bitmap.BuildableBitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.source.IBitmapTextureAtlasSource;
import org.andengine.opengl.texture.atlas.buildable.builder.BlackPawnTextureAtlasBuilder;
import org.andengine.opengl.texture.atlas.buildable.builder.ITextureAtlasBuilder.TextureAtlasBuilderException;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.util.debug.Debug;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;

public class ResourcesManager
{
    //---------------------------------------------
    // VARIABLES
    //---------------------------------------------
    
    private static final ResourcesManager INSTANCE = new ResourcesManager();
    
    public Engine engine;
    public GameActivity activity;
    public BoundCamera camera;
    public VertexBufferObjectManager vbom;
    public ITextureRegion splash_region;
    private BitmapTextureAtlas splashTextureAtlas;
    
    public ITextureRegion menu_background_region;
    public ITextureRegion menu_button_region;
        
    private BuildableBitmapTextureAtlas menuTextureAtlas;
    
    public Font font;
    public Font menu_font;
    
    // Game Texture
    public BuildableBitmapTextureAtlas gameTextureAtlas;
        
    // Game Texture Regions
    public ITiledTextureRegion stone_region;
    public ITiledTextureRegion jewel_region;
    public ITiledTextureRegion wall_region;
    public ITiledTextureRegion ground_region;
    public ITiledTextureRegion explosion_region;
    public ITextureRegion control_region;
    public ITextureRegion control_knob_region;
    public ITextureRegion message_region;
    
    public ITextureRegion button_back_region;
    public ITextureRegion button_replay_region;
    public ITextureRegion button_next_region;
    
    public ITiledTextureRegion player_region;
    public ITiledTextureRegion enemy_region;
    
    // Selector Texture
    public BuildableBitmapTextureAtlas selectorTextureAtlas;
    public ITextureRegion level_icon_region;
    public ITextureRegion locked_region;
    
    //Options textures
    public BuildableBitmapTextureAtlas optionsTextureAtlas;
    public ITextureRegion options_background_region;
    public ITextureRegion checkbox_unchecked_region;
    public ITextureRegion checkbox_checked_region;
    public ITextureRegion button_left_region;
    public ITextureRegion button_right_region;
    
    // Game sounds
    public Sound pick_jewel;
    public Sound jewel_fall;
    public Sound stone_fall;
    public Sound player_death;
    public Sound level_complete;
    public Sound enemy_death;
    
    //---------------------------------------------
    // CLASS LOGIC
    //---------------------------------------------

    public void loadMenuResources()
    {
        loadMenuGraphics();
        loadMenuAudio();
//        loadMenuFonts();
    }
    
    public void unloadMenuResources()
    {
        unloadMenuGraphics();
        unloadMenuAudio();
//        unloadMenuFonts();
    }
    
    public void loadGameResources()
    {
        loadGameGraphics();
        loadGameAudio();
        loadGameFonts();
    }
    
    public void loadSelectorResources()
    {
    	loadSelectorGraphics();
    	loadSelectorFonts();
//    	loadSelectorAudio();
    }
    
    public void unloadSelectorResources()
    {
        unloadSelectorGraphics();
        unloadSelectorFonts();
//    	loadSelectorAudio();
    }
    
    public void unloadGameResources()
    {
    	unloadGameGraphics();
    	unloadGameAudio();
    	unloadGameFonts();
    }
    
    public void loadOptionsResources()
    {
        loadOptionsTextures();
//        loadOptionsFonts();
    }
    
    public void unloadOptionsResources()
    {
        unloadOptionsTextures();
//        unloadOptionsFonts();
    }
    
    //---------------------------------Menu---------------------------------------------------
    public void loadMenuGraphics()
    {
        //Log.d("myLogs", "loadMenuGraphics");
        BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/menu/");
        menuTextureAtlas = new BuildableBitmapTextureAtlas(activity.getTextureManager(), 1024, 1024, TextureOptions.BILINEAR);
        menu_background_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(menuTextureAtlas, activity, "menu_background.png");
        menu_button_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(menuTextureAtlas, activity, "button.png");
               
        try 
        {
            this.menuTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 0));
            this.menuTextureAtlas.load();
        } 
        catch (final TextureAtlasBuilderException e)
        {
            Debug.e(e);
        }
    }
    
    public void unloadMenuGraphics()
    {
        //Log.d("myLogs", "unloadMenuTextures");
        menuTextureAtlas.unload();
        menu_background_region = null;
        menu_button_region = null;
        menuTextureAtlas = null;
    }
    
    public void loadMenuAudio()
    {
        //Log.d("myLogs", "loadMenuAudio");
    }
    
    public void unloadMenuAudio()
    {
        //Log.d("myLogs", "unloadMenuAudio");
    }
    
    public void loadMenuFonts()
    {
        //Log.d("myLogs", "loadMenuFonts");
        final ITexture mainFontTexture = new BitmapTextureAtlas( activity.getTextureManager(), 512, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA );
        FontFactory.setAssetBasePath("font/");
        menu_font = FontFactory.createStrokeFromAsset( activity.getFontManager(), mainFontTexture, activity.getAssets(), "font.ttf", 70, true, Color.WHITE, 1, Color.BLACK, false);
        menu_font.load();
    }
    
    public void unloadMenuFonts()
    {
        //Log.d("myLogs", "unloadMenuFonts");
        font.unload();
        font = null;
    }
    
    //----------------------------Game----------------------------------------
    public void loadGameGraphics()
    {
        //Log.d("myLogs", "loadGameGraphics");
        BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/game/");
        gameTextureAtlas = new BuildableBitmapTextureAtlas(activity.getTextureManager(), 1024, 1024, TextureOptions.BILINEAR);
        
        wall_region = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset( gameTextureAtlas, activity, "wall.png", 1, 1 );
        ground_region = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset( gameTextureAtlas, activity, "ground.png", 1, 1 );
        stone_region = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset( gameTextureAtlas, activity, "stone.png", 1, 1 );
        jewel_region = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset( gameTextureAtlas, activity, "jewel.png", 1, 1 );
        player_region = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset( gameTextureAtlas, activity, "player.png", 3, 4);
        enemy_region = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset( gameTextureAtlas, activity, "enemy.png", 4, 2);
        control_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( gameTextureAtlas, activity, "onscreen_control_base.png");
        control_knob_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( gameTextureAtlas, activity, "onscreen_control_knob.png" );
        message_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( gameTextureAtlas, activity, "message_background.png");
        button_back_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( gameTextureAtlas, activity, "back.png" );
        button_replay_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( gameTextureAtlas, activity, "replay.png" );
        button_next_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( gameTextureAtlas, activity, "next.png" );
        explosion_region = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset( gameTextureAtlas, activity, "wave.png", 5, 1);
        
        try 
        {
            this.gameTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 0));
            this.gameTextureAtlas.load();
        } 
        catch (final TextureAtlasBuilderException e)
        {
            Debug.e(e);
        }
    }
    
    public void unloadGameGraphics()
    {
        //Log.d("myLogs", "unloadGameTextures");
        gameTextureAtlas.unload();
        wall_region = null;
        ground_region = null;
        stone_region = null;
        jewel_region = null;
        player_region = null;
        enemy_region = null;
        control_region = null;
        control_knob_region = null;
        message_region = null;
        button_back_region = null;
        button_replay_region = null;
        button_next_region = null;
        explosion_region = null;
        gameTextureAtlas = null;
    }
   
   public void loadGameAudio()
   {
       //Log.d("myLogs", "loadGameAudio");
       final SharedPreferences prefrences = activity.getPreferences( Context.MODE_PRIVATE );
//       final float musicVolume = prefrences.getBoolean("musicOn", true) ? 1.0f : 0;
       final float soundVolume = prefrences.getBoolean("soundOn", true) ? 1.0f : 0;
       
       SoundFactory.setAssetBasePath("mfx/");
       
       try {
           this.pick_jewel = SoundFactory.createSoundFromAsset(this.engine.getSoundManager(), activity, "pick_jewel.wav");
           this.jewel_fall = SoundFactory.createSoundFromAsset(this.engine.getSoundManager(), activity, "jewel_fall.wav");
           this.stone_fall = SoundFactory.createSoundFromAsset(this.engine.getSoundManager(), activity, "stone_fall.wav");
           this.player_death = SoundFactory.createSoundFromAsset(this.engine.getSoundManager(), activity, "player_death.wav");
           this.level_complete = SoundFactory.createSoundFromAsset(this.engine.getSoundManager(), activity, "level_complete.wav");
           this.enemy_death = SoundFactory.createSoundFromAsset(this.engine.getSoundManager(), activity, "enemy_death.wav");
       } catch (final IOException e) {
           Debug.e(e);
       }
       
       this.pick_jewel.setVolume(soundVolume);
       this.jewel_fall.setVolume(soundVolume);
       this.stone_fall.setVolume(soundVolume);
       this.player_death.setVolume(soundVolume);
       this.level_complete.setVolume(soundVolume);
       this.enemy_death.setVolume(soundVolume);
   }
   
   public void unloadGameAudio()
   {
       //Log.d("myLogs", "unloadGameAudio");
       this.pick_jewel = null;
       this.jewel_fall = null;
       this.stone_fall = null;
       this.player_death = null;
       this.level_complete = null;
       this.enemy_death = null;
   }
   
   public void loadGameFonts()
   {
       //Log.d("myLogs", "loadGameFonts");
       final ITexture mainFontTexture = new BitmapTextureAtlas( activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA );
       FontFactory.setAssetBasePath("font/");
       font = FontFactory.createStrokeFromAsset( activity.getFontManager(), mainFontTexture, activity.getAssets(), "gothic.ttf", 60, true, Color.WHITE, 0, Color.WHITE, false);
       font.load();
   }
   
   public void unloadGameFonts()
   {
       //Log.d("myLogs", "unloadGameFonts");
       font.unload();
       font = null;
   }
    
    //---------------------Selector-------------------------------------------------
    public void loadSelectorGraphics() 
    {
        //Log.d("myLogs", "loadSelectorGraphics");
    	BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/selector/");
    	selectorTextureAtlas = new BuildableBitmapTextureAtlas(activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR);
    	
        level_icon_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( selectorTextureAtlas, activity, "level.png" );
        locked_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( selectorTextureAtlas, activity, "locked.png" );
        
        try 
        {
            this.selectorTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 0));
            this.selectorTextureAtlas.load();
        } 
        catch (final TextureAtlasBuilderException e)
        {
            Debug.e(e);
        }
	}
    
    public void unloadSelectorGraphics()
    {
        //Log.d("myLogs", "unloadSelectorGraphics");
        selectorTextureAtlas.unload();
        level_icon_region = null;
        locked_region = null;
        selectorTextureAtlas = null;
    }
    
    public void loadSelectorFonts()
    {
        //Log.d("myLogs", "loadSelectorFonts");
        final ITexture mainFontTexture = new BitmapTextureAtlas( activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA );
        FontFactory.setAssetBasePath("font/");
        font = FontFactory.createStrokeFromAsset(activity.getFontManager(), mainFontTexture, activity.getAssets(), "font.ttf", 48, true, Color.BLACK, 0, Color.WHITE, false);
        font.load();
    }
    
    public void unloadSelectorFonts()
    {
        //Log.d("myLogs", "unloadSelectorFonts");
        font.unload();
        font = null;
    }
    
    //----------------------------Options-------------------------------------------------
    public void loadOptionsTextures()
    {
        //Log.d("myLogs", "loadOptionsTextures");
    	BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/options/");
    	optionsTextureAtlas = new BuildableBitmapTextureAtlas(activity.getTextureManager(), 1024, 1024, TextureOptions.BILINEAR);
    	
    	checkbox_unchecked_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( optionsTextureAtlas, activity, "checkbox_unchecked.png" );
    	checkbox_checked_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset( optionsTextureAtlas, activity, "checkbox_checked.png" );
    	options_background_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(optionsTextureAtlas, activity, "options_background.png"); 
    	button_left_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(optionsTextureAtlas, activity, "left.png"); 
    	button_right_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(optionsTextureAtlas, activity, "right.png"); 
    	
    	try 
    	{
    		this.optionsTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 0));
    		this.optionsTextureAtlas.load();
    	} 
    	catch (final TextureAtlasBuilderException e)
    	{
    		Debug.e(e);
    	}
    }
    
    public void loadOptionsFonts()
    {
        //Log.d("myLogs", "loadOptionsFonts");
        final ITexture mainFontTexture = new BitmapTextureAtlas( activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA );
        FontFactory.setAssetBasePath("font/");
        menu_font = FontFactory.createStrokeFromAsset( activity.getFontManager(), mainFontTexture, activity.getAssets(), "font.ttf", 70, true, Color.WHITE, 1, Color.BLACK, false);
        menu_font.load();

    }
    
    public void unloadOptionsFonts()
    {
        //Log.d("myLogs", "unloadOptionsFonts");
        menu_font.unload();
        menu_font = null;
    }
    
    public void unloadOptionsTextures()
    {
        //Log.d("myLogs", "unloadOptionsTextures");
    	optionsTextureAtlas.unload();
    	checkbox_unchecked_region = null;
    	checkbox_checked_region = null;
    	options_background_region = null;
    	button_left_region = null;
    	button_right_region = null;
    	optionsTextureAtlas = null;
    }
    
    //--------------------------------Splash-------------------------------------------
    public void loadSplashScreen()
    {
        BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
        splashTextureAtlas = new BitmapTextureAtlas(activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR);
        splash_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(splashTextureAtlas, activity, "splash.png", 0, 0);
        splashTextureAtlas.load();
    }
    
    public void unloadSplashScreen()
    {
        splashTextureAtlas.unload();
        splash_region = null;
        splashTextureAtlas = null;
    }
   
    //-----------------------------------------------------------------------------------
    public void onActivityPaused()
    {
        this.engine.stop();
    }
    
    public void onActivityResumed()
    {
		engine.start();
    }
    
    /**
     * @param engine
     * @param activity
     * @param camera
     * @param vbom
     * <br><br>
     * We use this method at beginning of game loading, to prepare Resources Manager properly,
     * setting all needed parameters, so we can latter access them from different classes (eg. scenes)
     */
    public static void prepareManager(Engine engine, GameActivity activity, BoundCamera camera, VertexBufferObjectManager vbom)
    {
        getInstance().engine = engine;
        getInstance().activity = activity;
        getInstance().camera = camera;
        getInstance().vbom = vbom;
    }
    
    //---------------------------------------------
    // GETTERS AND SETTERS
    //---------------------------------------------
    
    public static ResourcesManager getInstance()
    {
        return INSTANCE;
    }
}
